﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using MyCompany.MyProject.Common.GlobalVaribale;
using MyCompany.MyProject.Model;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;

#nullable disable

namespace MyCompany.MyProject.Common.HttpContextUser;

public class AspNetUser : IUser
{
    private readonly IHttpContextAccessor accessor;
    private readonly ILogger<AspNetUser> logger;

    public AspNetUser(IHttpContextAccessor accessor, ILogger<AspNetUser> logger)
    {
        this.accessor = accessor;
        this.logger = logger;
    }

    public string Name => GetName();

    private string GetName()
    {
        if (IsAuthenticated() && accessor.HttpContext.User.Identity.Name.IsNotEmptyOrNull())
        {
            return accessor.HttpContext.User.Identity.Name;
        }
        else
        {
            if (!string.IsNullOrEmpty(GetToken()))
            {
                var getNameType = Permission.IsUseIds4 ? "name" : "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name";
                return GetUserInfoFromToken(getNameType).FirstOrDefault().ObjToString();
            }
        }
        return "";
    }

    public long ID => GetClaimValueByType("jti").FirstOrDefault().ObjToLong();
    public long TenantId => GetClaimValueByType("TenantId").FirstOrDefault().ObjToLong();

    public MessageModel<string> MessageModel { get; set; }

    /// <summary>
    ///  判断用户是否已授权
    /// </summary>
    /// <returns></returns>
    public bool IsAuthenticated()
    {
        return accessor.HttpContext?.User?.Identity?.IsAuthenticated ?? false;
    }


    public string GetToken()
    {
        var token = accessor.HttpContext.Request.Headers["Authorization"].ObjToString().Replace("Bearer ", "");
        if (!token.IsNullOrEmpty())
        {
            return token;
        }


        return token;
    }

    public List<string> GetUserInfoFromToken(string claimType)
    {
        var jwtHandler = new JwtSecurityTokenHandler();
        var token = GetToken();

        if (token.IsNotEmptyOrNull() && jwtHandler.CanReadToken(token))
        {
            var jwtToken = jwtHandler.ReadJwtToken(token);
            return (from item in jwtToken.Claims
                    where item.Type == claimType
                    select item.Value).ToList();
        }
        return new List<string>();
    }


    public IEnumerable<Claim> GetClaimsIdentity()
    {
        if (accessor.HttpContext == null) return ArraySegment<Claim>.Empty;
        if (!IsAuthenticated()) return GetClaimsIdentity(GetToken());
        var claims = accessor.HttpContext.User?.Claims.ToList();
        var headers = accessor.HttpContext.Request.Headers;
        foreach (var header in headers)
        {
            claims.Add(new Claim(header.Key, header.Value));
        }
        return claims;
    }

    public IEnumerable<Claim> GetClaimsIdentity(string token)
    {
        var jwtHandler = new JwtSecurityTokenHandler();

        if (token.IsNotEmptyOrNull() && jwtHandler.CanReadToken(token))
        {
            var jwtToken = jwtHandler.ReadJwtToken(token);
            return jwtToken.Claims;
        }
        return new List<Claim>();
    }

    public List<string> GetClaimValueByType(string claimType)
    {
        return (from item in GetClaimsIdentity()
                where item.Type == claimType
                select item.Value).ToList();
    }
}
